package com.dh.convert.node;

import java.util.ArrayList;
import java.util.LinkedHashMap;

import com.dh.convert.constants.Constants;
import com.dh.convert.constants.TypeEnum;
import com.dh.convert.utils.ClassUtils;

public class BeanNode {

	public static TreeNode object2Node(Class<?> c) {
		if (ClassUtils.isMap(c))
			return new MapNode().bulidRootNode(c);
		if (ClassUtils.isCommon(c))
			return null;
		if (c.isArray())
			return new ArrayNode().bulidEntryNode(c);
		if (ClassUtils.isColltion(c))
			return new CollectionNode().bulidEntryNode(c);
		return new ObjectNode().bulidRootNode(c);
	}

	public static TreeNode getNode(String childNodeName,TypeEnum type, Class<?> currentClass) {
		TreeNode childNode = null;
		if (type == null) {
			childNode = new ValueNode();
			childNode.setNodeName(childNodeName);
			childNode.setCurrentClass(currentClass);
			childNode.isCommon(Boolean.TRUE);
			return childNode;
		}
		switch (TypeEnum.type(childNodeName)) {
		case MAP:
			childNodeName = childNodeName.substring(1);
			childNode = new MapNode();
			childNode.setCurrentClass(LinkedHashMap.class);
			childNode.isMap(Boolean.TRUE);
			childNode.setNodeName(childNodeName);
			break;
		case CONTEXT:
			childNode = new ContextNode().build();
			break;
		case LIST:
			childNodeName = childNodeName.substring(1);
			String entryClassName = getListEntryClass(childNodeName);
			Class<?> entryClass = ClassUtils.getTypeClass(entryClassName);
			boolean hasEntryClass = entryClass!=null;
			childNode = new CollectionNode().bulidEntryNode(entryClass);
			childNode.setEntryClass(hasEntryClass?entryClass:LinkedHashMap.class);
			childNode.setCurrentClass(ArrayList.class);
			childNode.isColltion(Boolean.TRUE);
			childNode.setNodeName(childNodeName.substring(0, 
					entryClass==null?childNodeName.length():childNodeName.indexOf(Constants.BRACKETS_PREFIX)));
			childNode.isNestIng(hasEntryClass);
			childNode.isCollectionMapping(hasEntryClass);
			break;
		case ARRAY:
			childNodeName = childNodeName.substring(1);
			childNode = new ArrayNode().setEntryClass(currentClass);
			childNode.setCurrentClass(ArrayList.class);
			childNode.isArray(Boolean.TRUE);
			childNode.setNodeName(childNodeName);
			break;
		default:
			break;
		}
		return childNode;
	}

	public static String getNameWithoutFlag(String path) {
		int index = path.indexOf(Constants.POINT);
		index = (index == -1 ? path.length() : index);
		if (TypeEnum.type(path) == null)
			return path.substring(0, index);
		return path.substring(1, index);
	}

	public static String getNameWithFlag(String path) {
		int index = path.indexOf(Constants.POINT);
		index = (index == -1 ? path.length() : index);
		return path.substring(0, index);
	}
	public static String getListEntryClass(String nodeName){
		int startIndex = nodeName.indexOf(Constants.BRACKETS_PREFIX);
		if(startIndex!=-1){
			int endIndex = nodeName.lastIndexOf(Constants.BRACKETS_ENDINDEX);
			return endIndex==-1?null:nodeName.substring(startIndex+1, endIndex).replaceAll(Constants.MARK, Constants.POINT);
		}
		return null;
	}
}
